package com.agileai.esb.smc.controller.monitor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONObject;

import com.agileai.domain.DataParam;
import com.agileai.domain.DataRow;
import com.agileai.esb.component.RuntimeAnalysis;
import com.agileai.esb.component.RuntimeStat;
import com.agileai.esb.smc.bizmoduler.analysis.MessageFlowStatManage;
import com.agileai.esb.smc.bizmoduler.sysres.SysUserManage;
import com.agileai.esb.smc.domain.User;
import com.agileai.hotweb.annotation.PageAction;
import com.agileai.hotweb.common.BeanFactory;
import com.agileai.hotweb.controller.core.BaseHandler;
import com.agileai.hotweb.domain.FormSelect;
import com.agileai.hotweb.renders.AjaxRenderer;
import com.agileai.hotweb.renders.LocalRenderer;
import com.agileai.hotweb.renders.ViewRenderer;
import com.agileai.util.StringUtil;

public class MFRuntimeStatListHandler
        extends BaseHandler {
    public MFRuntimeStatListHandler() {
        super();
    }

	public ViewRenderer prepareDisplay(DataParam param){
		MessageFlowStatManage service = lookupService(MessageFlowStatManage.class);
		SysUserManage userManage = this.lookupService(SysUserManage.class);
		
		List<DataRow> appRecords = service.findAppRecords();
		User user = (User) this.getUser();
		if(!user.isAdmin()){
			String userId = user.getId();
			HashMap<String,DataRow> userAuthRecords = userManage.findAuthAppMap(userId);
			List<DataRow> results = new ArrayList<DataRow>();
			for (int i = 0; i < appRecords.size(); i++) {
				DataRow appRecord = appRecords.get(i);
				String appName = appRecord.getString("APP_NAME");
				if (userAuthRecords.containsKey(appName)){
					results.add(appRecord);
				}
			}
			appRecords = results;
		}
		FormSelect appNameSelect = new FormSelect();
		appNameSelect.setKeyColumnName("APP_NAME");
		appNameSelect.setValueColumnName("APP_NAME");
		appNameSelect.putValues(appRecords);
		String appSelect = param.get("appName");
		
		if(StringUtil.isNotNullNotEmpty(param.get("appName"))){
			appNameSelect.setSelectedValue(appSelect);
		}
		
		param.put("appName", appNameSelect);
		this.setAttribute("appName",appNameSelect);	
		
		this.setAttributes(param);
		processPageAttributes(param);
		return new LocalRenderer(getPage());
	}    
	
    protected void processPageAttributes(DataParam param) {

    }
    
	@PageAction
	public ViewRenderer query(DataParam param){
		return prepareDisplay(param);
	}
    
    @PageAction
    public ViewRenderer loadMonitorData(DataParam param){
    	int page = param.getInt("page");
		int rows = param.getInt("rows");
		String appName = param.getString("appName");
    	String responseText = buildJsonText(page,rows,appName);
    	return new AjaxRenderer(responseText);
    }

    @PageAction
    public ViewRenderer resetMonitor(DataParam param){
    	String responseText = FAIL;
    	try {
        	MessageFlowStatManage messageFlowStatManage = (MessageFlowStatManage) BeanFactory.instance().getBean("messageFlowStatManageService");
    		ConcurrentHashMap<String,RuntimeStat> runtimeStats = RuntimeAnalysis.geInstance(true).getTransitRuntimeStatMap();
    		messageFlowStatManage.insertStatRecords(runtimeStats);
    		responseText = SUCCESS;			
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(),e);
		}
    	return new AjaxRenderer(responseText);
    }    
    
    private String buildJsonText(int page,int rows,String appName){
    	String result = null;
    	try {
    		RuntimeStat[] runtimeStatArray = RuntimeAnalysis.geInstance(false).getRuntimeStats();
    		
    		User user = (User) this.getUser();
    		if(!user.isAdmin()){
    			List<RuntimeStat> runtimeStatList = new ArrayList<RuntimeStat>();
    			SysUserManage userManage = this.lookupService(SysUserManage.class);
    			String userId = user.getId();
    			HashMap<String,DataRow> userAuthRecords = userManage.findAuthAppMap(userId);

    			for (int i=0;i < runtimeStatArray.length;i++){
    				RuntimeStat runtimeStat = runtimeStatArray[i];
    				String tempAppName = runtimeStat.getAppName();
    				if (userAuthRecords.containsKey(tempAppName)){
    					runtimeStatList.add(runtimeStat);
    				}
    			}
    			runtimeStatArray = runtimeStatList.toArray(new RuntimeStat[0]);
    		}
    		
        	JSONArray jsonArray = new JSONArray();
        	JSONObject json = new JSONObject();
        	int start = (page - 1) * rows;
        	int end = start + rows;
        	if(runtimeStatArray.length < end){
        		end = runtimeStatArray.length;
        	}
        	if(StringUtil.isNotNullNotEmpty(appName)){
        		int index = 0;
        		for (int i= start;i < end;i++){
            		RuntimeStat runtimeStat = runtimeStatArray[i];
            		JSONObject jsonObject = new JSONObject();
            		if(appName.equals(runtimeStat.getAppName())){
            			jsonObject.put("statId",runtimeStat.getStatId());
                		jsonObject.put("appName",runtimeStat.getAppName());
                		jsonObject.put("messageFlowId",runtimeStat.getMessageFlowId());
                		jsonObject.put("messageFlowName",runtimeStat.getMessageFlowName());
                		jsonObject.put("messageFlowAlias",runtimeStat.getMessageFlowAlias());
                		jsonObject.put("messageFlowType",runtimeStat.getMessageFlowType());
                		jsonObject.put("totalCount",runtimeStat.getTotalCount());
                		jsonObject.put("successCount",runtimeStat.getSuccessCount());
                		jsonObject.put("failureCount",runtimeStat.getFailureCount());
                		jsonObject.put("maxRuntime",runtimeStat.getMaxRuntime());
                		jsonObject.put("minRuntime",runtimeStat.getMinRuntime());
                		jsonObject.put("averageRuntime",runtimeStat.getTotalRuntime()/runtimeStat.getTotalCount());
                		jsonArray.put(jsonObject);
                		index++;
            		}
            	}
    	        json.put("rows", jsonArray);
    	        json.put("total", index);
        	}else{
        		for (int i= start;i < end;i++){
            		RuntimeStat runtimeStat = runtimeStatArray[i];
            		JSONObject jsonObject = new JSONObject();
            		jsonObject.put("statId",runtimeStat.getStatId());
            		jsonObject.put("appName",runtimeStat.getAppName());
            		jsonObject.put("messageFlowId",runtimeStat.getMessageFlowId());
            		jsonObject.put("messageFlowName",runtimeStat.getMessageFlowName());
            		jsonObject.put("messageFlowAlias",runtimeStat.getMessageFlowAlias());
            		jsonObject.put("messageFlowType",runtimeStat.getMessageFlowType());
            		jsonObject.put("totalCount",runtimeStat.getTotalCount());
            		jsonObject.put("successCount",runtimeStat.getSuccessCount());
            		jsonObject.put("failureCount",runtimeStat.getFailureCount());
            		jsonObject.put("maxRuntime",runtimeStat.getMaxRuntime());
            		jsonObject.put("minRuntime",runtimeStat.getMinRuntime());
            		jsonObject.put("averageRuntime",runtimeStat.getTotalRuntime()/runtimeStat.getTotalCount());
            		jsonArray.put(jsonObject);
            	}
    	        json.put("rows", jsonArray);
    	        json.put("total", runtimeStatArray.length);
        	}
        	result = json.toString();
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
		}
    	return result;
    }
    
    protected void initParameters(DataParam param) {

    }
}